﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;

namespace ParserGenerator.ParserConstruction
{
    [Serializable]
    public sealed class ParserAutomatonItemLookaheadSetsTable : ReadOnlyDictionary<ParserAutomatonState, ParserAutomatonItemLookaheadSets>
    {
        internal ParserAutomatonItemLookaheadSetsTable()
            : base(new Dictionary<ParserAutomatonState, ParserAutomatonItemLookaheadSets>())
        {
        }

        internal void Add(ParserAutomatonState state, ParserAutomatonItemLookaheadSets sets)
        {
            if (state == null)
                throw new ArgumentNullException(nameof(state));
            if (sets == null)
                throw new ArgumentNullException(nameof(sets));
            Dictionary.Add(state, sets);
        }

        internal bool TryGetLookaheadSet(ParserAutomatonState state, ParserAutomatonItem item, out ParserAutomatonItemLookaheadSet set)
        {
            if (state == null)
                throw new ArgumentNullException(nameof(state));
            if (item == null)
                throw new ArgumentNullException(nameof(item));
            set = null;
            ParserAutomatonItemLookaheadSets sets;
            if (!Dictionary.TryGetValue(state, out sets))
                return false;
            return sets.TryGetValue(item, out set);
        }

        internal ParserAutomatonItemLookaheadSet GetLookaheadSet(ParserAutomatonState state, ParserAutomatonItem item)
        {
            if (state == null)
                throw new ArgumentNullException(nameof(state));
            if (item == null)
                throw new ArgumentNullException(nameof(item));
            ParserAutomatonItemLookaheadSets sets;
            if (!Dictionary.TryGetValue(state, out sets))
            {
                sets = new ParserAutomatonItemLookaheadSets(state);
                Dictionary.Add(state, sets);
            }
            ParserAutomatonItemLookaheadSet set;
            if (!sets.TryGetValue(item, out set))
            {
                set = new ParserAutomatonItemLookaheadSet(state, item);
                sets.Add(item, set);
            }
            return set;
        }
    }
}
